package com.example.controller;

import com.example.model.WebUser;
import com.example.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@RestController
public class AuthController {

    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
    private final UserService userService;

    public AuthController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/sign-up")
    public ResponseEntity<Map<String, String>> signUp(@RequestBody Map<String, String> request) {
        try {
            if (request == null || !request.containsKey("username") || !request.containsKey("email") || !request.containsKey("password")) {
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Missing required fields: username, email, and password");
                return ResponseEntity.badRequest().body(response);
            }

            String message = userService.signUp(
                request.get("username"),
                request.get("email"),
                request.get("password")
            );
            Map<String, String> response = new HashMap<>();
            response.put("msg", message);
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            Map<String, String> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    @PostMapping("/sign-in")
    public ResponseEntity<Map<String, String>> signIn(@RequestBody Map<String, String> request) {
        System.out.println("Received request for sign-in");
        try {
            if (request == null || !request.containsKey("username") || !request.containsKey("password")) {
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Missing required fields: username and password");
                return ResponseEntity.badRequest().body(response);
            }

            String token = userService.signIn(
                request.get("username"),
                request.get("password")
            );
            Map<String, String> response = new HashMap<>();
            response.put("jwt", token);
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            Map<String, String> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    @PostMapping("/sign-out")
    public ResponseEntity<Map<String, String>> signOut(@RequestHeader("Authorization") String authHeader) {
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Invalid authorization header");
                return ResponseEntity.badRequest().body(response);
            }

            String token = authHeader.substring(7);
            userService.signOut(token);
            Map<String, String> response = new HashMap<>();
            response.put("msg", "Successfully signed out");
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            Map<String, String> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    @PostMapping("i")
    public ResponseEntity<Map<String, String>> testCredential(
            @RequestHeader("Authorization") String authHeader,
            @RequestParam("csr") MultipartFile csrFile) {
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Invalid authorization header");
                return ResponseEntity.badRequest().body(response);
            }

            String token = authHeader.substring(7);
            WebUser user = userService.getUserFromToken(token);
            
            // Check if credentials already exist
            if (user.getHmacKey() != null || user.getCertificate() != null) {
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Credentials have already been generated");
                return ResponseEntity.badRequest().body(response);
            }

            userService.processCredential(token, csrFile);
            Map<String, String> response = new HashMap<>();
            response.put("msg", "Credential processed successfully");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, String> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    @GetMapping("/download-certificate")
    public ResponseEntity<byte[]> downloadCertificate(@RequestHeader("Authorization") String authHeader) {
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                return ResponseEntity.badRequest().build();
            }

            String token = authHeader.substring(7);
            WebUser user = userService.getUserFromToken(token);
            
            if (user.getCertificate() == null) {
                return ResponseEntity.notFound().build();
            }

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", "certificate.pem");
            
            return new ResponseEntity<>(user.getCertificate(), headers, HttpStatus.OK);
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().build();
        }
    }
    
    @GetMapping("/download-key")
    public ResponseEntity<Map<String, String>> getKey(@RequestHeader(value = "Authorization", required = false) String authHeader) {
        try {
            logger.debug("Received request for /get-key with header: {}", authHeader);
            
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                logger.warn("Invalid authorization header received");
                Map<String, String> response = new HashMap<>();
                response.put("msg", "Invalid authorization header");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }

            String token = authHeader.substring(7);
            logger.debug("Processing token for /get-key");
            
            WebUser user = userService.getUserFromToken(token);
            logger.debug("Found user: {}", user.getUsername());
            
            if (user.getHmacKey() == null) {
                logger.warn("No HMAC key found for user: {}", user.getUsername());
                Map<String, String> response = new HashMap<>();
                response.put("msg", "No HMAC key found. Please process a CSR file first.");
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
            }

            Map<String, String> response = new HashMap<>();
            response.put("key", user.getHmacKey());
            logger.debug("Successfully retrieved HMAC key for user: {}", user.getUsername());
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            logger.error("Error in /get-key: {}", e.getMessage(), e);
            Map<String, String> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
        }
    }

    @GetMapping("/check-credential-status")
    public ResponseEntity<Map<String, Object>> checkCredentialStatus(
            @RequestHeader("Authorization") String authHeader) {
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                Map<String, Object> response = new HashMap<>();
                response.put("msg", "Invalid authorization header");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }

            String token = authHeader.substring(7);
            WebUser user = userService.getUserFromToken(token);
            
            Map<String, Object> response = new HashMap<>();
            response.put("hasCredentials", user.getHmacKey() != null && user.getCertificate() != null);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("msg", e.getMessage());
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
        }
    }
}